package com.yanqu.road.server.gameplayer.module.activity.unionwar;

import com.yanqu.road.entity.activity.ActivityConditionInfo;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.ActivityRewardResult;
import com.yanqu.road.entity.activity.UserActivityConditionData;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.player.UserInfo;
import com.yanqu.road.entity.unionwar.BaseUnionGuessInfo;
import com.yanqu.road.entity.unionwar.UserUnionWarGuessData;
import com.yanqu.road.logic.bussiness.activity.UnionWarActivityBusiness;
import com.yanqu.road.pb.activity.unionwar.UnionWarActivityServerProto;
import com.yanqu.road.pb.cross.activity.CrossActivityProto;
import com.yanqu.road.pb.rank.UnionActivityRankProto;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.logic.unionwar.UnionWarActivityData;
import com.yanqu.road.server.manger.activity.unionwar.UnionPhaseWarMgr;
import com.yanqu.road.server.manger.activity.unionwar.UnionWar;
import com.yanqu.road.server.manger.activity.unionwar.UnionWarActivityMgr;
import com.yanqu.road.server.manger.log.LogMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.union.GameUnionActivityGroupMgr;
import com.yanqu.road.server.pb.PlayerPb;
import com.yanqu.road.server.protocol.CrossProtocol;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;

import javax.annotation.Nullable;
import java.util.*;


public class UserUnionWarGuess {
    private GamePlayer player;
    private int activityId;
    private int stage;
    private UserUnionWarGuessData userUnionWarGuessData;
    private int conditionType;

    public UserUnionWarGuess(GamePlayer player, int activityId, int stage, @Nullable UserUnionWarGuessData userUnionWarGuessData) {
        this.player = player;
        this.activityId = activityId;
        this.stage = stage;
        this.userUnionWarGuessData = userUnionWarGuessData;
        if (this.stage == 1) {
            this.conditionType = UnionWarActivityMgr.CONDITION_TYPE_INTEGRAL_GUESS;
        } else if (this.stage == 2) {
            this.conditionType = UnionWarActivityMgr.CONDITION_TYPE_FINAL_GUESS;
        }
    }

    public void guess(List<UnionWarActivityServerProto.UnionWarGuessDataTemp> guessUnionList) {
        if (userUnionWarGuessData == null) {
            initUserUnionWarGuessData();
        }
        List<BaseUnionGuessInfo> baseUnionGuessInfos = new ArrayList<>();
        for (UnionWarActivityServerProto.UnionWarGuessDataTemp dataTemp : guessUnionList) {
            BaseUnionGuessInfo baseUnionGuessInfo = new BaseUnionGuessInfo();
            baseUnionGuessInfo.setServerId(dataTemp.getServerId());
            baseUnionGuessInfo.setUnionUid(dataTemp.getUnionUid());
            baseUnionGuessInfos.add(baseUnionGuessInfo);
        }
        userUnionWarGuessData.setGuessUnionBaseInfos(baseUnionGuessInfos);
        userUnionWarGuessData.setModifyTime(System.currentTimeMillis());
        syncCrossGuessData();
        syncClientGuessData();
    }

    private void syncClientGuessData() {
        UnionWar unionWar = UnionPhaseWarMgr.getUnionWar(activityId);
        if (unionWar != null) {
            unionWar.syncGuessListMsg(player);
        }
    }

    private void syncCrossGuessData() {
        UnionWarActivityServerProto.SyncCrossGuessDataMsg.Builder reqMsg = UnionWarActivityServerProto.SyncCrossGuessDataMsg.newBuilder();
        reqMsg.setActivityId(activityId);
        reqMsg.setStage(stage);
        int myGroupId = GameUnionActivityGroupMgr.getViewDataGroupId(activityId, player.getUserId());
        for (BaseUnionGuessInfo guessUnionBaseInfo : userUnionWarGuessData.getGuessUnionBaseInfos()) {
            int tempGroupId = GameUnionActivityGroupMgr.getGroupId(activityId, guessUnionBaseInfo.getUnionUid());
            if(myGroupId != tempGroupId){
                myGroupId = tempGroupId;
            }
            reqMsg.addUnionUid(guessUnionBaseInfo.getUnionUid());
        }
        UserInfo userInfo = UserMgr.getUserInfo(userUnionWarGuessData.getUserId());
        reqMsg.setPlayerBaseInfo(PlayerPb.parsePlayerBaseTempMsg(userInfo));
        player.sendUnionActivityGroupPacket(CrossProtocol.C_CROSS_UNION_WAR_SYNC_GUESS_DATA, reqMsg, activityId, myGroupId);
    }

    private void initUserUnionWarGuessData() {
        userUnionWarGuessData = new UserUnionWarGuessData();
        userUnionWarGuessData.setActivityId(activityId);
        userUnionWarGuessData.setStage(stage);
        userUnionWarGuessData.setUserId(player.getUserId());
        userUnionWarGuessData.setGuessUnionBaseInfos(new ArrayList<>());
        userUnionWarGuessData.setModifyTime(System.currentTimeMillis());
        userUnionWarGuessData.setInsertOption();
    }

    public ActivityRewardResult getReward(CrossActivityProto.UnionWarRankMsgMsg msg, boolean isCrossNotify) {
        synchronized (this) {
            ActivityRewardResult result = new ActivityRewardResult();
            ActivityInfo activityInfo = UnionWarActivityMgr.getOpenActivityInfo(activityId);
            if (activityInfo == null) {
                return result;
            }
            Map<Integer, Map<Integer, UnionWarActivityData>> activityDataMap = player.getModule(UnionWarActivityModule.class).getActivityDataMap();
            if (activityDataMap == null) {
                return result;
            }
            Map<Integer, UnionWarActivityData> dataMap = activityDataMap.get(activityId);
            if (dataMap == null) {
                return result;
            }
            UnionWarActivityData unionWarActivityData = dataMap.get(conditionType);
            if (unionWarActivityData == null) {
                return result;
            }
            UserActivityConditionData userActivityConditionData = unionWarActivityData.getFirstConditionData();
            if (userActivityConditionData == null) {
                return result;
            }
            if (userActivityConditionData.isGetReward()) {
                return result;
            }
            if (!isCrossNotify) {
                //发送跨服请求排行榜数据
                UnionWarActivityServerProto.UnionWarGetGuessRewardMsg.Builder reqMsg = UnionWarActivityServerProto.UnionWarGetGuessRewardMsg.newBuilder();
                reqMsg.setActivityId(activityId);
                reqMsg.setPhase(stage);

                int myGroupId = GameUnionActivityGroupMgr.getViewDataGroupId(activityId, player.getUserId());

                for (BaseUnionGuessInfo guessUnionBaseInfo : userUnionWarGuessData.getGuessUnionBaseInfos()) {
                    int groupId = GameUnionActivityGroupMgr.getGroupId(activityId, guessUnionBaseInfo.getUnionUid());
                    if(groupId != myGroupId){
                        UnionPhaseWarMgr.getLogger().info("activityId {} userId {} myGroupId {} guessDataId {}", activityInfo.getActivityId(), player.getUserId(), myGroupId, groupId);
                        myGroupId = groupId;
                        break;
                    }
                }
                player.sendUnionActivityGroupPacket(CrossProtocol.C_CROSS_UNION_WAR_GET_GUESS_REWARD, reqMsg, activityId, myGroupId);
                return result;
            }

            //比较结果 计算得分
            int guessScore = getGuessScore(msg);
            // 根据 conditionType 取conditionInfoList
            List<ActivityConditionInfo> activityConditionInfoList = UnionPhaseWarMgr.getActivityConditionInfoList(activityId, conditionType);
            ActivityConditionInfo activityConditionInfo = null;
            if (activityConditionInfoList != null) {
                activityConditionInfoList.sort(Comparator.comparing(o -> o.getParamList().get(3)));
                Collections.reverse(activityConditionInfoList);
                for (ActivityConditionInfo info : activityConditionInfoList) {
                    // 根据个数取到对应conditionInfo
                    if (info.getParamList().get(3).intValue() <= guessScore) {
                        activityConditionInfo = info;
                        break;
                    }
                    if (info.getParamList().get(3).intValue() == 0) {
                        activityConditionInfo = info;
                    }
                }
            }
            if (activityConditionInfo == null) {
                return result;
            }
            //取conditionInfo奖励发放
            Property reward = activityConditionInfo.getReward();
            result.setReward(PropertyHelper.parsePropertyToString(reward));
            result.setConditionId(activityConditionInfo.getConditionId());
            // 添加奖励
            player.getModule(CurrencyModule.class).addCurrency(reward, eLogMoneyType.Activity, eLogMoneyType.UnionWarActivityGuessReward);
            userActivityConditionData.setGetReward(true);
            player.getModule(UnionWarActivityModule.class).onActivityDataChange(unionWarActivityData);
            unionWarActivityData.finish(userActivityConditionData.getConditionId());

            LogMgr.addLogActivityReward(player.getUserId(), activityId, activityInfo.getType(), activityInfo.getChildType(),
                    activityConditionInfo.getConditionId(), guessScore, false, PropertyHelper.parsePropertyToString(reward));
            return result;
        }
    }

    public UserActivityConditionData getConditionData() {
        Map<Integer, Map<Integer, UnionWarActivityData>> activityDataMap = player.getModule(UnionWarActivityModule.class).getActivityDataMap();
        if (activityDataMap != null) {
            if (activityDataMap.containsKey(activityId)) {
                Map<Integer, UnionWarActivityData> dataMap = activityDataMap.get(activityId);
                if (dataMap.containsKey(conditionType)) {
                    UnionWarActivityData unionWarActivityData = dataMap.get(conditionType);
                    if (unionWarActivityData != null) {
                        return unionWarActivityData.getFirstConditionData();
                    }
                }
            }
        }
        return null;
    }

    public int getGuessScore(CrossActivityProto.UnionWarRankMsgMsg msg) {
        int score = 0;
        UnionActivityRankProto.UnionActivityRankListMsg rankList = msg.getRankList();
        if (stage == 1) {
            //前N名
            int n = 8;
            ActivityInfo activityInfo = UnionWarActivityMgr.getOpenActivityInfo(activityId);
            try {
                n = Integer.parseInt(activityInfo.getParam4().split(";")[2]);
            } catch (Exception e) {
                UnionPhaseWarMgr.getLogger().error(e.getMessage(), e);
            }
            for (int i = 0; i < n; i++) {
                if (i >= rankList.getRankListList().size()) {
                    break;
                }
                UnionActivityRankProto.UnionActivityRankTempMsg rank = rankList.getRankListList().get(i);
                for (BaseUnionGuessInfo guessInfo : userUnionWarGuessData.getGuessUnionBaseInfos()) {
                    if (Objects.equals(guessInfo.getUnionUid(), rank.getUnionUid())) {
                        score ++;
                    }
                }
            }
        } else if (stage == 2) {
            //冠亚军
            for (int i = 0; i < 2; i++) {
                if (i >= rankList.getRankListList().size() || i >= userUnionWarGuessData.getGuessUnionBaseInfos().size()) {
                    break;
                }
                UnionActivityRankProto.UnionActivityRankTempMsg rank = rankList.getRankListList().get(i);
                if (userUnionWarGuessData.getGuessUnionBaseInfos().get(i) != null) {
                    if (Objects.equals(userUnionWarGuessData.getGuessUnionBaseInfos().get(i).getUnionUid(), rank.getUnionUid())) {
                        score += i == 0 ? 2 : 1;
                    }
                }
            }
        }
        return score;
    }

    public UserUnionWarGuessData getUserUnionWarGuessData() {
        return userUnionWarGuessData;
    }

    public void save() {
        if (userUnionWarGuessData.isInsertOption()) {
            UnionWarActivityBusiness.addUserUnionWarGuessData(userUnionWarGuessData);
        } else if (userUnionWarGuessData.isUpdateOption()) {
            UnionWarActivityBusiness.updateUserUnionWarGuessData(userUnionWarGuessData);
        }
    }
}
